package com.networkmmc.demo.sql;

import cn.hutool.core.util.ArrayUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Sql语句工具类
 */
public class SqlUtils {

    /**
     * 判断是否数据库字段
     * @param col
     * @return
     */
    public static boolean notColumn(String col) {
        String s = col.substring(0, 1);
        String e = col.substring(col.length() - 1);
        if (s.equals(s.toLowerCase()) || !e.equals("_")) {
            return true;
        }
        return false;
    }

    /**
     * 将参数转换为批量参数执行参数
     * @param args
     * @return
     */
    public static List<Object[]> argsConvertToBatchArgs(List<Object> args) {
        List<Object[]> list = new ArrayList<>();
        Object[] par = new Object[args.size()];
        list.add(par);
        for (int j = 0; j < args.size(); j++) {
            Object o = args.get(j);
            if (o instanceof List) {
                List<Object[]> l = new ArrayList<>();
                for (Object[] params : list) {
                    for (Object o1 : (List) o) {
                        params[j] = o1;
                        l.add(params.clone());
                    }
                }
                list.clear();
                list.addAll(l);
            } else {
                for (Object[] params : list) {
                    params[j] = o;
                }
            }
        }
        return list;
    }

    /**
     * 添加条件
     * @param sqlObj
     * @param map
     * @return
     */
    public static SqlObj addConditions(SqlObj sqlObj, Map<String, Object> map) {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (!SqlUtils.notColumn(entry.getKey())) {
                sqlObj.addConditions(entry.getKey(), entry.getValue());
            }
        }
        return sqlObj;
    }

    public static SqlObj addFields(SqlObj sqlObj, Map<String, Object> map) {
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (!SqlUtils.notColumn(entry.getKey())) {
                sqlObj.addFields(entry.getKey(), entry.getValue());
            }
        }
        return sqlObj;
    }

    /**
     * INSERT
     *
     * @param sqlObj
     * @return
     */
    public static String insert(SqlObj sqlObj) {
        return new StringBuffer().append(Contants.INSERT).append(sqlObj.getTableName()).append(Contants.LEFT_BRACKET + "`")
                .append(ArrayUtil.join(sqlObj.getFields().toArray(), "`" + Contants.SEPARATORS + "`")).append("`" + Contants.RIGHT_BRACKET)
                .append(Contants.VALUES).append(Contants.LEFT_BRACKET)
                .append(ArrayUtil.join(sqlObj.getFieldsPlaceholder().toArray(), Contants.SEPARATORS))
                .append(Contants.RIGHT_BRACKET).toString();
    }

    public static String update(SqlObj sqlObj) {
        StringBuffer sbStr = new StringBuffer().append(Contants.UPDATE).append(sqlObj.getTableName()).append(Contants.SET);
        for (int i = 0; i < sqlObj.getFields().size(); i++) {
            if (i == sqlObj.getFields().size() - 1) {
                sbStr.append(sqlObj.getFields().get(i)).append(Contants.EQUALS).append(Contants.PLACEHOLDER);
            } else {
                sbStr.append(sqlObj.getFields().get(i)).append(Contants.EQUALS).append(Contants.PLACEHOLDER).append(Contants.SEPARATORS);
            }
        }
        sbStr.append(Contants.WHERE).append(Contants.DEFAULT_CONDITION);
        for (String conditionFields : sqlObj.getConditionFields()) {
            sbStr.append(Contants.AND).append(conditionFields).append(Contants.EQUALS).append(Contants.PLACEHOLDER);
        }
        return sbStr.toString();
    }

    public static String delete(SqlObj sqlObj) {
        StringBuffer sbStr = new StringBuffer().append(Contants.DELETE).append(Contants.FROM).append(sqlObj.getTableName())
                .append(Contants.WHERE).append(Contants.DEFAULT_CONDITION);
        for (String conditionFields : sqlObj.getConditionFields()) {
            sbStr.append(Contants.AND).append(conditionFields).append(Contants.EQUALS).append(Contants.PLACEHOLDER);
        }
        return sbStr.toString();
    }

    public static String select(SqlObj sqlObj) {
        StringBuffer sbStr = new StringBuffer().append(Contants.SELECT).append(Contants.ALL).append(Contants.FROM).append(sqlObj.getTableName())
                .append(Contants.WHERE).append(Contants.DEFAULT_CONDITION);
        for (String conditionFields : sqlObj.getConditionFields()) {
            sbStr.append(Contants.AND).append(conditionFields).append(Contants.EQUALS).append(Contants.PLACEHOLDER);
        }
        return sbStr.toString();
    }

    public static String searchSelect(SqlObj sqlObj) {
        StringBuffer sbStr = new StringBuffer().append(Contants.SELECT).append(Contants.ALL).append(Contants.FROM).append(sqlObj.getTableName())
                .append(Contants.WHERE).append(Contants.DEFAULT_CONDITION);
        List<String> conditionFields = sqlObj.getConditionFields();
        List<String> conditionPlaceholder = sqlObj.getConditionPlaceholder();
        for (int i = 0; i < conditionFields.size(); i++) {
            String conditionField = conditionFields.get(i);
            sbStr.append(Contants.AND).append(conditionField).append(conditionPlaceholder.get(i)).append(Contants.PLACEHOLDER);
        }
        return sbStr.toString();
    }

    public static int dataIndex(PageObj pageObj) {
        if (pageObj.getPage() == 1) {
            return 0;
        }
        return pageObj.getPage() * pageObj.getPageSize();
    }

    public static int dataLimit(PageObj pageObj) {
        return pageObj.getPage() * pageObj.getPageSize();
    }

//    private static void searchCondition(SqlObj sqlObj) {
//        if (sqlObj.getConditionFields().size() == 0) {
//            return;
//        }
//        String busType = MD5Util.encode(sqlObj.getTableName());
//        List<String> placeholders = new ArrayList<>();
//        List<Object> values = new ArrayList<>();
//        List<String> fields = new ArrayList<>();
//        List<String> conditionFields = sqlObj.getConditionFields();
//        for (int i = 0; i < conditionFields.size(); i++) {
//            String conditionField = conditionFields.get(i);
//            //获取缓存
//            Map<String, Object> busCache = CacheHelper.get(busType + conditionField);
//            String colType = StrUtil.toString(busCache.get("COL_TYPE_"));
//            String queryMatch = StrUtil.toString(busCache.get("QUERY_MATCH_"));
//            if (StrUtil.equals(Contants.COL_DATE, colType)) {
//                String dtType = StrUtil.toString(busCache.get("DT_TYPE_"));
//                Calendar calendar = Calendar.getInstance();
//                if(StrUtil.equals(dtType, Contants.SQL_MATCH_DT_TYPE_SEDT)){
//                    //查询传递两个日期，start/end，包含start，不包含end
//                    Map<String, Object> dtMap = JSONUtil.parseObj(sqlObj.getConditionValues().get(i));
//                    //开始日期
//                    long startDt = NumberUtil.parseLong(StrUtil.toString(dtMap.get("start")));
//                    calendar.setTimeInMillis(startDt);
//                    fields.add(conditionField);
//                    placeholders.add(Contants.GREATER_EQUAL);
//                    values.add(SqlDtUtils.day(calendar));
//                    //结束日期
//                    long endDt = NumberUtil.parseLong(StrUtil.toString(dtMap.get("end")));
//                    calendar.setTimeInMillis(endDt);
//                    fields.add(conditionField);
//                    placeholders.add(Contants.LESS);
//                    values.add(SqlDtUtils.day(calendar));
//                }else if(StrUtil.equals(dtType, Contants.SQL_MATCH_DT_TYPE_MONTH)){
//                    //查询传递一个日期，截取年月部分做查询
//                    long dt = NumberUtil.parseLong(StrUtil.toString(sqlObj.getConditionValues().get(i)));
//                    //开始时间
//                    calendar.setTimeInMillis(dt);
//                    fields.add(conditionField);
//                    placeholders.add(Contants.GREATER_EQUAL);
//                    values.add(SqlDtUtils.month(calendar));
//                    //结束时间
//                    fields.add(conditionField);
//                    placeholders.add(Contants.LESS);
//                    values.add(SqlDtUtils.nextMonth(calendar));
//                }else if(StrUtil.equals(dtType, Contants.SQL_MATCH_DT_TYPE_YEAR)){
//                    //查询传递一个日期，截取年部分做查询
//                    long dt = NumberUtil.parseLong(StrUtil.toString(sqlObj.getConditionValues().get(i)));
//                    //开始时间
//                    calendar.setTimeInMillis(dt);
//                    fields.add(conditionField);
//                    placeholders.add(Contants.GREATER_EQUAL);
//                    values.add(SqlDtUtils.year(calendar));
//                    //结束时间
//                    fields.add(conditionField);
//                    placeholders.add(Contants.LESS);
//                    values.add(SqlDtUtils.nextYear(calendar));
//                }else if(StrUtil.equals(dtType, Contants.SQL_MATCH_DT_TYPE_DAY)){
//                    //查询传递一个日期，截取年月日做查询
//                    long dt = NumberUtil.parseLong(StrUtil.toString(sqlObj.getConditionValues().get(i)));
//                    //开始时间
//                    calendar.setTimeInMillis(dt);
//                    fields.add(conditionField);
//                    placeholders.add(Contants.GREATER_EQUAL);
//                    values.add(SqlDtUtils.day(calendar));
//                    //结束时间
//                    fields.add(conditionField);
//                    placeholders.add(Contants.LESS);
//                    values.add(SqlDtUtils.nextDay(calendar));
//                }
//            } else {
//                fields.add(conditionField);
//                placeholders.add(replacePlaceholder(queryMatch));
//                if(StrUtil.equals(queryMatch, Contants.MATCH_CONTAIN)){
//                    values.add(StrUtil.format("%{}%", sqlObj.getConditionValues().get(i)));
//                }else{
//                    values.add(sqlObj.getConditionValues().get(i));
//                }
//            }
//        }
//        sqlObj.setConditionFields(fields);
//        sqlObj.setConditionPlaceholder(placeholders);
//        sqlObj.setConditionValues(values);
//    }

    public static String replacePlaceholder(String queryMatch){
        switch (queryMatch) {
            case Contants.MATCH_EQUAL:
                return Contants.EQUAL;
            case Contants.MATCH_LESS:
                return Contants.LESS;
            case Contants.MATCH_LESS_EQUAL:
                return Contants.LESS_EQUAL;
            case Contants.MATCH_GREATER:
                return Contants.GREATER;
            case Contants.MATCH_GREATER_EQUAL:
                return Contants.GREATER_EQUAL;
            default:
                return Contants.CONTAIN;
        }
    }

}
